首先到公眾運輸平台找 api
let flights = [];
fetch(flightApi)
.then(blob => {
return blob.json();
})
.then(data => {
flights = data;
});
fetch()
是一個可以將 api 給抓下來的方法,更早以前是使用XMLHttpRequest, XMLHttpRequest 可以讓用戶不必重新請求整個網頁,而是只重新渲染其中的一部分
fetch()
可以讓我們在索取遠端伺服器的資料同時,去跑接下來的程式碼
非同步的語言在向遠端伺服器要資料的同時
會繼續跑之後的程式碼
所以被稱為非同步
而同步的語言則是一行一行跑程式碼
這會導致在根遠端伺服器請求資料的同時
會一直卡著不動,等到資料請求完畢,才會繼續執行程式碼
這會導致用戶體驗差
而fetch(url)
回來的東西會是一個promise
然後使用.then()
來取得的資料
.then
是promise
的一個 method ,在 fetch 取得檔案後要程式做的事情
我們使用第一個.then
方法回傳的還是一個promise
物件
其內有我們所需要的航班資訊使用.json
將之轉成 json 檔
最後再將這些資料(這裡是物件)放到flights
array 內
接著我們要來監聽 input 事件, 只要 input 內容有更動就會觸發事件
const searchInput = document.querySelector('.search');
const suggestions = document.querySelector('.suggestions');
searchInput.addEventListener('input', displayMatches);
監聽好後,要來找符合要求的字了,我們要傳出符合要求的「航空公司 ID 」「班機號碼」和「機場 ID 」,但在這之前要先去了解一下正則表達式
之前做的筆記,正則表達式
我們將陣列 flights 用 .filter()
篩選,並要符合正則表達式的要求字串才會被 return
match()
match()
也是 string 的 method,.match(regex)
表示字串要符合所規範的正則表達式才會留下
function findMatches(wordToMatch, flights) {
return flights.filter((flight) => {
const regex = new RegExp(wordToMatch, 'gi');
return (`${flight.AirlineID}${flight.FlightNumber}`).match(regex) || flight.ArrivalAirportID.match(regex);
});
};
接著用 matchArr
去裝剛剛成功篩選出的字串,我們希望 match 的字要被 highlight 起來,
所以還要對 matchArr
做修改,得到一個修改過的 Array ,這個描述,就是 .map()
。我們要將 match的字用<span class="hl"></span>
包起來,這樣就可以吃到 css 特效了。就讓 .replace()
來幫幫我們吧!
function displayMatches() {
const matchArr = findMatches(this.value, flights);
const html = matchArr.map(flight => {
const regex = new RegExp(this.value, 'gi');
const arrivalAirportId = flight.ArrivalAirportID.replace(regex, `<span class="hl">${this.value}</span>`);
const flightNumber = (`${flight.AirlineID}${flight.FlightNumber}`).replace(regex, `<span class="hl">${this.value}</span>`);
const regexT = new RegExp("T", 'gi');
const scheduleDepartureTime = flight.ScheduleDepartureTime === undefined ? "no-data" : flight.ScheduleDepartureTime.replace(regexT, ' ');
return `
<li>
<span class="flight-number">${flightNumber}</span>
<span class="schedule-depar-time">${scheduleDepartureTime}</span>
<span class="airline">${arrivalAirportId}</span>
</li>
`
}).join('');
接著我想要再加個起飛時間!
const scheduleDepartureTime = flight.ScheduleDepartureTime === undefined ? "no-data" : flight.ScheduleDepartureTime.replace(regexT, ' ');
在取得航班表定起飛時間時遇到了一點麻煩
因為並不是每一筆資料都有表定起飛時間
所以如果沒有使用判別式
將會取得兩種資料2018-08-19T09:10
和 undefind
這時候如果想要將"T"
改成" "
會在沒有資料的地方出現問題
因為undefined
是不被允許使用replace
的
所以我們要講undefined
的資料以"no-data"顯示
最後得到的是一個新的 array ,但是 html 看不懂 array ,他只看得懂字串
所以最後我們再使用 .join('')
讓 array 內的每個項目都用''(空字串)
串起來,
再使用 innerHTLML
渲染到網頁上